
#ifndef _SWARM_H
#  define _SWARM_H

#  include <math.h>
#  include <gtk/gtk.h>
#  include <pthread.h>

#  include <config.h>
#  include <sw_types.h>
#  include <native.h>

/* Data structures. */

typedef struct sw_force {

  unsigned int force_type;
  double       force_constant;
  double       force_order;
  char        *name;

} sw_force;

typedef struct sw_insect {

  char      *type;

  sw_xmm_vec loc;
  sw_xmm_vec vel;
  sw_id      id;

  /* Transient stuff. */
  sw_xmm_vec f_net;
  sw_xmm_vec d_loc;
  sw_xmm_vec d_vel;

  /* List of forces on the insect. */
  sw_size_t  f_len_r;  // Length of frespond list
  sw_force  **frespond;
  sw_size_t  f_len_e;  // Length of femit list
  sw_force  **femit;

  /* Render info. */
  GdkColor  color;

  /* Insect lock */
  pthread_mutex_t lock;

} sw_insect;

typedef struct sw_swarm {

  char       *name;

  /* Defines the box in which the simulation takes place. */
  sw_xmm_vec  size;

  /* Swarm entities */
  sw_size_t   swarm_size;   // Number of insects in swarm.
  sw_size_t   swarm_space;  // Max num of insects that can be held.
  sw_insect **swarm;

  /* Global list of all forces. */
  sw_size_t   f_len;
  sw_force   *forces;

  /* User defined variables. */
  double      tau;
  double      entropy;
  double      sim_len;
  int         threads;
  int         fps;

  /* Swarm lock */
  pthread_mutex_t lock;

} sw_swarm;

// Some extern vars. For use in the library itself.
extern sw_swarm *internal_sw;

/* Functions. */

int        sw_init(int *, char ***);
void       sw_init_signals();
sw_swarm  *sw_load_swarm(char *);
sw_swarm  *sw_swarm_new();
void       sw_print_lib_info();
void       sw_print_force_table(sw_swarm *);
void       sw_print_swarm_info(sw_swarm *);
int        sw_simulate();
void       sw_exit(int);
void       sw_add_insect(sw_swarm *, sw_insect *);
void      _sw_set_internal(sw_swarm *);
void      _sw_load_sym_table_data(sw_swarm *);
void      _sw_simulate_frame();

// Force functions

sw_force  *sw_new_force();
void       sw_print_force(sw_force *);
void       sw_swarm_add_force(sw_swarm *, sw_force *);
int        sw_find_force_offset(sw_swarm *, char *);

// Insect functions

sw_insect *sw_new_insect();
void       sw_print_insect(sw_insect *);

// Random number wrapper.

double     sw_random();
void       sw_srand(long);
int        sw_init_rand(double, double);
void       sw_print_rand_info();

// Display functions.

int        sw_init_display(int *, char ***, int, int);
void       sw_start_display();
void       sw_display_insect(sw_insect *);
void       sw_display_swarm(sw_swarm *);
void       sw_clear_display();
void       sw_flush_display();

#endif
